package com.example.librarymanagementproject2.mq;

import com.example.librarymanagementproject2.Common.config.RabbitConfig;
import com.example.librarymanagementproject2.Common.exception.GlobalException;
import com.example.librarymanagementproject2.Common.message.BorrowSuccessMessage;
import com.example.librarymanagementproject2.converter.BorrowRecordConverter;
import com.example.librarymanagementproject2.mapper.BookMapper;
import com.example.librarymanagementproject2.mapper.BorrowRecordMapper;
import com.example.librarymanagementproject2.mapper.UserMapper;
import com.example.librarymanagementproject2.model.document.BorrowRecordDocument;
import com.example.librarymanagementproject2.model.entity.Book;
import com.example.librarymanagementproject2.model.entity.BorrowRecord;
import com.example.librarymanagementproject2.model.entity.User;
import com.example.librarymanagementproject2.model.enums.BorrowStatus;
import com.example.librarymanagementproject2.service.EmailService;
import com.example.librarymanagementproject2.service.enums.BookEnum;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

/**
 * @ClassName BorrowRecord
 * @Description 图书借阅消费者
 * @Author Kx
 * @Date 2025/10/28 11:40
 * @Version 1.0
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class BorrowRecordConsumer {
    private final BookMapper bookMapper;
    private final BorrowRecordMapper borrowRecordMapper;
    private final RedisTemplate<String, Object> redisTemplate;
    private final EmailService emailService;
    private final BorrowRecordConverter borrowRecordConverter;
    private final ElasticsearchOperations elasticsearchTemplate;
    private final UserMapper userMapper;
    /**
     * @author: kx
     * @date: 2025/10/28 14:37
     * @param borrowId : 借阅记录ID
     * @description: 监听图书借阅状态超时消息
    */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = RabbitConfig.BORROW_RECORD_SUCCESS_DELAY_QUEUE, durable = "true"),
            exchange = @Exchange(name = RabbitConfig.BORROW_RECORD_SUCCESS_DELAY_EXCHANGE, type = ExchangeTypes.DIRECT),
            key = RabbitConfig.BORROW_RECORD_SUCCESS_DELAY_ROUTING_KEY
    ))
    public void receive(Long borrowId) {
         // 获取图书借阅记录
        BorrowRecord borrowRecord = borrowRecordMapper.getBorrowRecordById(borrowId);

        // 判断图书借阅记录是否存在
        if (borrowRecord == null) {
            throw new GlobalException(500, "图书借阅记录不存在");
        }

        // 判断图书借阅记录状态是否为未借出
        if (borrowRecord.getStatus() == BorrowStatus.AVAILABLE) {
            // 设置图书借阅记录为已失效
            borrowRecord.setStatus(BorrowStatus.INVALID);

            try {
                // 修改图书借阅记录状态
                borrowRecordMapper.updateBorrowRecordStatus(borrowRecord);

                // 回填缓存库存
                redisTemplate.opsForValue().increment(BookEnum.BOOK_STOCK_PREFIX.value() + borrowRecord.getBookId());
            } catch (Exception e) {
                throw new GlobalException(500, "修改图书借阅记录状态失败");
            }
        }

        // 判断图书借阅记录状态是否为已借出
        if (borrowRecord.getStatus() == BorrowStatus.BORROWED) {
            try {
                // 扣减图书信息数据库库存
                bookMapper.updateBookStock(borrowRecord.getBookId());
            } catch (Exception e) {
                throw new GlobalException(500, "扣减图书信息数据库库存失败");
            }
        }
    }

    /**
     * @author: kx
     * @date: 2025/10/28 20:19
     * @param borrowSuccessMessage : 借阅成功信息
     * @description: 借阅之后先添加借阅文档信息再发送邮件
    */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = RabbitConfig.BORROW_RECORD_SUCCESS_QUEUE, durable = "true"),
            exchange = @Exchange(name = RabbitConfig.BORROW_RECORD_EXCHANGE, type = ExchangeTypes.DIRECT),
            key = RabbitConfig.BORROW_RECORD_SUCCESS_ROUTING_KEY
    ))
    public void receive(BorrowSuccessMessage borrowSuccessMessage) {
        // 把借阅信息、图书信息、用户信息转换为文档信息
        BorrowRecordDocument borrowRecordDocument = borrowRecordConverter.borrowRecordToBorrowRecordDocument(borrowSuccessMessage.getBorrowRecord(), borrowSuccessMessage.getBook(), borrowSuccessMessage.getUser());
        // 添加索引
        elasticsearchTemplate.save(borrowRecordDocument);
        // 发送邮件
        emailService.sendBookBorrowCode(borrowSuccessMessage.getBook().getTitle(), borrowSuccessMessage.getUser().getEmail(), borrowSuccessMessage.getBorrowRecord().getId());
    }

    /**
     * @author: kx
     * @date: 2025/10/29 16:10
     * @param borrowId : 借阅记录ID
     * @description: 修改借阅文档信息
    */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = RabbitConfig.BORROW_RECORD_OPERATION_QUEUE, durable = "true"),
            exchange = @Exchange(name = RabbitConfig.BORROW_RECORD_EXCHANGE, type = ExchangeTypes.DIRECT),
            key = RabbitConfig.BORROW_RECORD_OPERATION_ROUTING_KEY
    ))
    public void updateBorrowRecordIndexAfterCodeVerification(Long borrowId) {
        // 获取借阅记录
        BorrowRecord borrowRecord = borrowRecordMapper.getBorrowRecordById(borrowId);
        if (borrowRecord == null) {
            throw new GlobalException(500, "借阅记录不存在");
        }

        // 获取用户信息
        User user = userMapper.getUserById(borrowRecord.getUserId());
        // 获取图书信息
        Book book = bookMapper.getBookById(borrowRecord.getBookId());

        // 转换为文档信息
        BorrowRecordDocument borrowRecordDocument = borrowRecordConverter.borrowRecordToBorrowRecordDocument(borrowRecord, book, user);

        // 修改文档信息
        elasticsearchTemplate.update(borrowRecordDocument);
    }
}
